home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / util / conv / Cas2Wav.lha / Original stuff / CAS2WAV.C next >
Encoding:
C/C++ Source or Header  |  2002-02-18  |  70.7 KB  |  2,100 lines

  1. /*****************************************************************************
  2. **
  3. **  Copyright 1998, 1999 by Ernest R. Schreurs.
  4. **  All rights reserved.
  5. **  Use of this source code is allowed under the following conditions:
  6. **  You must inform people that you based your work on this stuff.
  7. **  If you charge a fee in any form for your product, you must inform people
  8. **  that this stuff is available free of charge.
  9. **  Refer to the documentation for more information.
  10. **
  11. *****************************************************************************/
  12. #define MODULE  "CAS2WAV.C"
  13. /*****************************************************************************
  14. **  NAME: CAS2WAV.C
  15. **
  16. **  Author            : Ernest R. Schreurs
  17. **  Date              : January 3, 1999
  18. **  Release           : 01.00
  19. **
  20. **  Description       : This program will convert a .cas cassette image file
  21. **                      to a .wav file.
  22. **
  23. *****************************************************************************/
  24.  
  25. /*****************************************************************************
  26. ==  INCLUDE FILES
  27. *****************************************************************************/
  28. #include <stdio.h>              /* For printf() and gets()              */
  29. #include <ctype.h>              /* For isalnum() and toupper()          */
  30. #include <fltenv.h>             /* For sin() exceptions                 */
  31. #include <math.h>               /* For sin()                            */
  32. #include <stdlib.h>             /* For the exit function                */
  33. #include <string.h>             /* String and memory stuff              */
  34.  
  35. /*****************************************************************************
  36. ==  DEFINED SYMBOLS
  37. *****************************************************************************/
  38.  
  39. #ifndef FALSE
  40. #define FALSE               0
  41. #endif
  42. #ifndef TRUE
  43. #define TRUE                1
  44. #endif
  45.  
  46. #ifndef NULL
  47. #define NULL                0
  48. #endif
  49. #define PATH_LEN            128             /* Maximum path length          */
  50.  
  51. #define BUF_LEN             80              /* fgets buffer length          */
  52. #define SUCCESS             1               /* Success is non-zero          */
  53. #define FAILURE             0               /* Failure is zero              */
  54. #define ZERO_LEVEL          128             /* Zero level for wav sample    */
  55.  
  56. /*
  57. **  A tape record starts with a Pre-Record Write Tone.
  58. **  Then we find bytes, usually 132, each starting with a startbit,
  59. **  eight data bits, lsb first, followed by a stopbit.
  60. **  This is all coded in mark and space tones, as defined below.
  61. */
  62. #define FSK_MARK            1               /* Mark tone represents a 1     */
  63. #define FSK_SPACE           0               /* Space tone represents a 0    */
  64. #define FSK_1               1               /* A 1 bit is a mark            */
  65. #define FSK_0               0               /* A 0 bit is a space           */
  66. #define FSK_PRWT            1               /* PRWT tone is a mark          */
  67. #define FSK_STARTBIT        0               /* Startbit is a space          */
  68. #define FSK_STOPBIT         1               /* Stopbit is a mark            */
  69.  
  70. /*
  71. **  Definitions for the mark and space tone frequencies.
  72. */
  73. #define FSK_TONE_MARK       5327            /* Frequency of mark tone       */
  74. #define FSK_TONE_SPACE      3995            /* Frequency of space tone      */
  75. #define MARK_TABLE_LEN      44100L          /* Length of mark tone table    */
  76. #define SPACE_TABLE_LEN     44100L          /* Length of space tone table   */
  77.  
  78. /*****************************************************************************
  79. ==  MACRO DEFINITIONS
  80. *****************************************************************************/
  81. /*
  82. **  Macro for casting stuff to requirements of stupid
  83. **  standard library functions.
  84. */
  85.  
  86. #define FGETS( buf, buf_len, file_ptr )                                 \
  87.     (void *)fgets( (char *)buf, (int)buf_len, (FILE *)file_ptr )
  88.  
  89. #define STRLEN( str )                                                   \
  90.     strlen( (const char *)(str) )
  91.  
  92. /*
  93. **  Macro for getting input from the terminal,
  94. **  allowing the user to exit with either control Z or
  95. **  inputting the string ^Z to indicate intention of
  96. **  terminating the program.
  97. */
  98. #define GET_BUF()                                                           \
  99. {                                                                           \
  100.     if ( FGETS( buf, BUF_LEN, stdin )  ==  NULL )                           \
  101.     {                                                                       \
  102.         printf( "Terminated by ^Z\n" );                                     \
  103.         exit(0);                                                            \
  104.     }                                                                       \
  105.     if ( memcmp( buf, "^Z", 2 ) == 0 || memcmp( buf, "^z", 2 ) == 0  )      \
  106.     {                                                                       \
  107.         printf( "Terminated by ^Z\n" );                                     \
  108.         exit(0);                                                            \
  109.     }                                                                       \
  110. }
  111.  
  112. #define PRINT( lst )                                                        \
  113. {                                                                           \
  114.     if( diagnostics )                                                       \
  115.     {                                                                       \
  116.         printf lst;                                                         \
  117.     }                                                                       \
  118. }
  119.  
  120. /*****************************************************************************
  121. ==  TYPE and STRUCTURE DEFINITIONS
  122. *****************************************************************************/
  123. typedef     unsigned char   bool;   /* Boolean value                        */
  124. typedef     unsigned char   ubyte;  /* Exactly eight bits, unsigned         */
  125. typedef     short           int16;  /* At least 16 bits, signed             */
  126. typedef     unsigned short  uint16; /* At least 16 bits, unsigned           */
  127. typedef     long            int32;  /* At least 32 bits, signed             */
  128. typedef     unsigned long   uint32; /* At least 32 bits, unsigned           */
  129.  
  130. /*
  131. **  Cassette file header.
  132. */
  133.  
  134. typedef struct
  135. {
  136.     ubyte       cas_record_id[4];       /* Cassette record type             */
  137.     ubyte       cas_len_lo;             /* Record length low byte           */
  138.     ubyte       cas_len_hi;             /* Record length high byte          */
  139.     ubyte       cas_aux1;               /* Type dependant data              */
  140.     ubyte       cas_aux2;               /* Type dependant data              */
  141.     ubyte       cas_data[8192];         /* Data                             */
  142. } cas_blk;
  143.  
  144. /*****************************************************************************
  145. ==  IMPORTED VARIABLES
  146. *****************************************************************************/
  147. /*****************************************************************************
  148. ==  LOCAL ( HIDDEN ) VARIABLES
  149. *****************************************************************************/
  150. static FILE *   cas_file;               /* Cassette image file              */
  151. static FILE *   wav_file;               /* Wave file                        */
  152.  
  153. static cas_blk  cas_rec;                /* The cassette record buffer       */
  154. static uint32   cas_len;                /* Length of cassette data          */
  155.  
  156. static uint32   baudrate;               /* Baudrate                         */
  157. static bool     baudrate_fixed;         /* Fixed baudrate entered           */
  158. static uint32   bitlen;                 /* Number of samples in one bit     */
  159. static uint32   bit_stretch;            /* Number of samples for stretch    */
  160. static uint32   bytelen;                /* Number of samples in one byte    */
  161. static bool     diagnostics;            /* Print diagnostic data            */
  162. static bool     header_written;         /* Did we write out a header yet    */
  163. static bool     format_pure;            /* Format is pure sine waves        */
  164. static bool     format_sine;            /* Format is sine waves             */
  165. static bool     format_square;          /* Format is square waves           */
  166. static bool     zero_transition;        /* Do a transition at zero level    */
  167. static uint32   test_tape;              /* Generate test tape only          */
  168. static uint32   mark_tone;              /* Frequency of mark tone           */
  169. static uint32   space_tone;             /* Frequency of space tone          */
  170. static uint32   leader;                 /* Fixed length of leader           */
  171. static uint32   irg;                    /* Fixed length of Inter Record Gap */
  172. static uint32   pos;                    /* Number of bytes in wav file      */
  173. static uint32   pos_chunk_size;         /* Position in wav file for length  */
  174. static uint32   pos_file_size;          /* Position in wav file for length  */
  175. static ubyte    number[4];              /* Buffer for numbers               */
  176. static ubyte *  mark;                   /* Buffer with mark tone generator  */
  177. static ubyte *  space;                  /* Buffer with space tone generator */
  178. static ubyte *  ptr;                    /* Pointer to tone generator        */
  179. static uint32   table_len;              /* Length of generator table        */
  180. static uint32   prev_bitvalue;          /* Last bit value written           */
  181. static uint32   recno;                  /* Record number                    */
  182.  
  183. /*****************************************************************************
  184. ==  EXPORTED VARIABLES
  185. *****************************************************************************/
  186. /*****************************************************************************
  187. ==  IMPORTED FUNCTIONS
  188. *****************************************************************************/
  189. /*****************************************************************************
  190. ==  LOCAL ( HIDDEN ) FUNCTIONS
  191. *****************************************************************************/
  192. static void     cleanup( void );
  193. static uint32   process_header( void );
  194. static void     process_record( void );
  195. static uint32   read_record( void );
  196. static void     usage( char * cmd );
  197. static void     write_wav( char * buffer, uint32 buflen );
  198. static void     write_wav_bit( uint32 value, uint32 samples );
  199. static void     write_wav_number( uint32 value, uint32 buflen );
  200.  
  201. /*****************************************************************************
  202. ==  EXPORTED FUNCTIONS
  203. *****************************************************************************/
  204. int                 main();                 /* Normal entry point to it all */
  205.  
  206. /*****************************************************************************
  207. ==  LOCAL ( HIDDEN ) FUNCTIONS
  208. *****************************************************************************/
  209.  
  210. /*****************************************************************************
  211. **  NAME:  cleanup()
  212. **
  213. **  PURPOSE:
  214. **      Cleanup any mess that was created.
  215. **
  216. **  DESCRIPTION:
  217. **      This function will attempt to close all open files and
  218. **      free allocated memory.
  219. **
  220. **  INPUT:
  221. **      - The file pointers and paths are used.
  222. **
  223. **  OUTPUT:
  224. **      The function returns nothing.
  225. **
  226. */
  227.  
  228. static void         cleanup( void )
  229. {
  230.     if( wav_file )
  231.     {
  232.         fclose( wav_file );
  233.     }
  234.     if( cas_file )
  235.     {
  236.         fclose( cas_file );
  237.     }
  238.  
  239.     if( mark )
  240.         free( (void *)mark );
  241.  
  242.     if( space )
  243.         free( (void *)space );
  244.     return;
  245. }
  246.  
  247. /*****************************************************************************
  248. **  NAME:  process_header()
  249. **
  250. **  PURPOSE:
  251. **      Process the data from the header of the .cas file and store
  252. **      relevant information.  This will verify that the file truly is
  253. **      a cassette image file.
  254. **
  255. **  DESCRIPTION:
  256. **      This function will read the relevant data about the .cas file
  257. **      and verify it.
  258. **
  259. **  INPUT:
  260. **      Nothing.
  261. **      Data is read from the cassette image file.
  262. **
  263. **  OUTPUT:
  264. **      Prints results.
  265. **      Stores data related to the contents of the cassette image file.
  266. **      Returns SUCCESS if header was processed successfully.
  267. **      Returns FAILURE if some error occurred.
  268. **
  269. */
  270.  
  271. static uint32       process_header( void )
  272. {
  273.     uint32          bytes;                  /* Number of bytes read         */
  274.  
  275. /*
  276. **  Cassette image files usually look like this
  277. **
  278. **  char[4] = "FUJI", two chars record size lo/hi, two chars null
  279. **  char[4] = "baud", two chars null, two chars baudrate lo/hi
  280. **  char[4] = "data", two chars record size lo/hi, two chars PRWT lo/hi
  281. **  See below for more details.
  282. */
  283.  
  284. /*
  285. **  .cas files should begin with FUJI, followed by the size of the description.
  286. */
  287.     bytes = fread( (char *)&cas_rec, (int)1, (int)4, cas_file );
  288.     if( ( bytes < 4 ) || memcmp( cas_rec.cas_record_id, "FUJI", 4 ) )
  289.     {
  290.         fprintf(stderr, "\nThis is not a valid .cas file, it does not begin with \"FUJI\".\n");
  291.         return( FAILURE );
  292.     }
  293.  
  294. /*
  295. **  Get the remaining four bytes of the record header.
  296. */
  297.     bytes = fread( ((char *)&cas_rec)+4, (int)1, (int)4, cas_file );
  298.     if( bytes < 4 )
  299.     {
  300.         fprintf(stderr, "\nThis is not a valid .cas file, description length missing.\n");
  301.         return( FAILURE );
  302.     }
  303.  
  304. /*
  305. **  This looks like what we wanted, so we will call this success.
  306. **  Position the file at the beginning again.
  307. */
  308.     fseek( cas_file, 0L, SEEK_SET );    /* Go back to beginning of file */
  309.     return( SUCCESS );
  310. }
  311.  
  312. /*****************************************************************************
  313. **  NAME:  process_record()
  314. **
  315. **  PURPOSE:
  316. **      There is data in the cassette record buffer.  This must now be
  317. **      converted to the selected format.
  318. **
  319. **  DESCRIPTION:
  320. **      This function will take data from the record buffer and convert it
  321. **      to FSK bits.  The bits are coded as mark and space tones.
  322. **      These tones are output as wave data.
  323. **
  324. **  INPUT:
  325. **      Nothing.
  326. **      Data is taken from the cassette record buffer.
  327. **
  328. **  OUTPUT:
  329. **      Data is output to the file.
  330. **      The function returns nothing.
  331. **
  332. */
  333.  
  334. static void         process_record( void )
  335. {
  336.     uint32          bit;                    /* Number of bits processed     */
  337.     uint32          bitvalue;               /* Current bit level counting   */
  338.     ubyte           byte;                   /* Byte decoded from fsk data   */
  339.     uint32          bytes;                  /* Number of bytes read         */
  340.     uint32          change;                 /* Bit change index             */
  341.     uint32          changes;                /* Bit changes index            */
  342.     uint32          msecs;                  /* Number of milli-seconds      */
  343.     uint32          prwt;                   /* Length of the PRWT           */
  344.     uint32          bits[10];               /* Number of bits               */
  345.     uint32          remainder;              /* Left over samples            */
  346.     uint32          samples[10];            /* Number of samples per bit    */
  347.     uint32          total;                  /* Total sample count           */
  348.     uint32          total_bits;             /* Total number of bits         */
  349.  
  350. /*
  351. **  Currently, we only have three types of record:
  352. **  FUJI  A header/description record.
  353. **  baud  A record telling us the baudrate.
  354. **  data  A record with cassette data.
  355. */
  356.  
  357. /*
  358. **  If we find a header, and it is the first one, write the header
  359. **  for the wave file.
  360. */
  361.     if( memcmp( cas_rec.cas_record_id, "FUJI", 4 ) == 0 )
  362.     {
  363.         PRINT( ("\nDescription \"%.*s\".\n", (int)cas_len, cas_rec.cas_data) );
  364.         if( !header_written )
  365.         {
  366.             write_wav( (char *)"RIFF", (uint32)4L );
  367.             pos_file_size = pos;
  368.             write_wav_number( (uint32)0L, (uint32)4L );
  369.             header_written = TRUE;
  370.         }
  371.         write_wav( (char *)"WAVE", (uint32)4L );
  372.  
  373.         write_wav( (char *)"fmt ", (uint32)4L );
  374.         write_wav_number( (uint32)16L, (uint32)4L ); /* Header size */
  375.  
  376.         write_wav_number( (uint32)1L, (uint32)2L );  /* fmt tag 1 */
  377.         write_wav_number( (uint32)1L, (uint32)2L );  /* channels 1 */
  378.         write_wav_number( (uint32)44100L, (uint32)4L );  /* sample rate 44100 */
  379.         write_wav_number( (uint32)44100L, (uint32)4L );  /* Bytes per second */
  380.         write_wav_number( (uint32)1L, (uint32)2L );  /* Buffer alignment */
  381.  
  382.         write_wav_number( (uint32)8L, (uint32)2L );  /* bits per sample */
  383.  
  384.         write_wav( (char *)"data", (uint32)4L );
  385.         pos_chunk_size = pos;
  386.         write_wav_number( (uint32)0L, (uint32)4L );
  387.  
  388.         return;
  389.     }
  390.  
  391. /*
  392. **  If this is a baudrate record, change the baud rate, unless
  393. **  the user selected a fixed baudrate.
  394. */
  395.     if( memcmp( cas_rec.cas_record_id, "baud", 4 ) == 0 )
  396.     {
  397.         if( !baudrate_fixed )
  398.         {
  399.             baudrate = (((uint32)cas_rec.cas_aux2) << 8 ) + cas_rec.cas_aux1;
  400.             bytelen = ( 44100L * 10 ) / baudrate;
  401.             bitlen = 44100L / baudrate;
  402.         }
  403.         PRINT( ("\nBaudrate set to %lu.\n", baudrate) );
  404.         return;
  405.     }
  406.  
  407. /*
  408. **  If this is a plain old data record, encode the bits.
  409. */
  410.     if( memcmp( cas_rec.cas_record_id, "data", 4 ) == 0 )
  411.     {
  412.         prwt = (((uint32)cas_rec.cas_aux2) << 8 ) + cas_rec.cas_aux1;
  413.  
  414. /*
  415. **  If there is a fixed leader, and we did not write a leader yet,
  416. **  set the length of the leader.
  417. **  If this is a normal irg or other gap, any gap less than 3 seconds
  418. **  is considered an irg and if specified, the fixed irg is used.
  419. */
  420.         if( leader )
  421.         {
  422.             prwt = leader;
  423.             leader = 0;
  424.         }
  425.         else
  426.         {
  427.             if( irg )
  428.             {
  429.                 if( prwt < 3000 )
  430.                     prwt = irg;
  431.             }
  432.         }
  433.  
  434. /*
  435. **  Each record starts out with the PRWT.
  436. **  Then we write out all the bytes in the cassette record.
  437. **  The PRWT is measured in milli-seconds.  At a sample rate of
  438. **  44,100, this means the number of samples is 44.1 times the prwt value.
  439. */
  440.         write_wav_bit( FSK_PRWT, prwt * 44 + prwt / 10 );
  441.         recno++;
  442.         PRINT( ("\nRecord %lu at offset %lu PRWT = %lu with %lu data bytes.",
  443.                  recno, pos - pos_chunk_size - 4, prwt, cas_len ) );
  444.  
  445. /*
  446. **  Now process the data record byte by byte.
  447. */
  448.         for( bytes = 0; bytes < cas_len; bytes++ )
  449.         {
  450.  
  451. /*
  452. **  Since this is FSK, we accumulate the sample counts of the bits that
  453. **  are the same value.  This way, we can get a more precise baudrate.
  454. **  Encode and sum up like bits.  Begin with a startbit, then the databits,
  455. **  and finally the stopbit.
  456. **  We need ten bits to encode one byte (startbit and stopbit included)
  457. **  but since we are using integers here, we will divide the bytelength
  458. **  by ten after summing up the bits, for improved accuracy.
  459. */
  460.             bitvalue = FSK_STARTBIT;
  461.             samples[0] = bytelen;
  462.             bits[0] = 1;
  463.             changes = 0;
  464.             byte = cas_rec.cas_data[bytes];
  465.  
  466. /*
  467. **  Convert each byte to a string of 8 bits.
  468. **  Least significant bit is encoded first.
  469. **  If the bitvalue changes, start the new count,
  470. **  otherwise add the length of a bit to the sum.
  471. */
  472.             for( bit = 0; bit < 8; bit++ )
  473.             {
  474.                 if( ( byte & 0x01 ) != bitvalue )
  475.                 {
  476.                     bitvalue = byte & 0x01;
  477.                     changes++;
  478.                     samples[changes] = bytelen;
  479.                     bits[changes] = 1;
  480.                 }
  481.                 else
  482.                 {
  483.                     samples[changes] += bytelen;
  484.                     bits[changes]++;
  485.                 }
  486.                 byte = byte >> 1;
  487.             }
  488.  
  489. /*
  490. **  The last bit is the stop bit.  Add it to the length of the last bit(s)
  491. **  if they were mark, otherwise, make a final new count.
  492. */
  493.             if( bitvalue == FSK_STOPBIT )
  494.             {
  495.                 samples[changes] += bytelen;
  496.                 bits[changes]++;
  497.             }
  498.             else
  499.             {
  500.                 changes++;
  501.                 samples[changes] = bytelen;
  502.                 bits[changes] = 1;
  503.             }
  504.  
  505. /*
  506. **  Now that we have the bits encoded, we must still divide the bytelength
  507. **  by ten, thus we must divide our sums by ten.  We must make sure that
  508. **  the baudrate is correct, so the total sum of the samples for all bits
  509. **  must be equal to the bytelength.  Distribute the remaining samples,
  510. **  caused by inaccuracy in the division, by checking the sum at every change.
  511. **  Keep a running total, and compute where we should be at, in order
  512. **  to compensate for truncation that occurs during the division.
  513. */
  514.             total = 0;
  515.             total_bits = 0;
  516.             for( change = 0; change <= changes; change++ )
  517.             {
  518.                 samples[change] /= 10;
  519.                 total += samples[change];
  520.                 total_bits += bits[change];
  521.                 remainder = (( total_bits * bytelen ) / 10 ) - total;
  522.                 samples[change] += remainder;
  523.                 total += remainder;
  524.             }
  525.  
  526. /*
  527. **  Now that we have the bits encoded, stretch the space bits.
  528. **  The table starts with the startbit, which is a space.  Steal the
  529. **  samples from the following mark bit(s).
  530. **  Even table entries are space, odd entries are mark, since they alternate.
  531. */
  532.             for( change = 0; change < changes; change++ )
  533.             {
  534.                 samples[change++] += bit_stretch;
  535.                 samples[change] -= bit_stretch;
  536.             }
  537.  
  538. /*
  539. **  Now output this stuff.
  540. **  There are at least two changes, since we have a start bit and
  541. **  a stop bit.  The bits may alternate several times, but we are
  542. **  certain that the last one will be a stop bit, which is a mark.
  543. **  Thus, process bits in pairs, alternating between space and mark.
  544. */
  545.             for( change = 0; change < changes; change++ )
  546.             {
  547.                 write_wav_bit( FSK_SPACE, samples[change++] );
  548.                 write_wav_bit( FSK_MARK, samples[change] );
  549.             }
  550.         }
  551.         return;
  552.     }
  553.  
  554.     PRINT( ("\nIn process_record() unknown record type %.4s %lu bytes data\n", &cas_rec, cas_len) );
  555.     return;
  556. }
  557.  
  558. /*****************************************************************************
  559. **  NAME:  read_record()
  560. **
  561. **  PURPOSE:
  562. **      Read a record into the cassette buffer.
  563. **
  564. **  DESCRIPTION:
  565. **      This function will read data from the cas file and store it in the
  566. **      cassette buffer.  One complete record is read into the buffer.
  567. **
  568. **  INPUT:
  569. **      Nothing.
  570. **      Data is read from the cas file.
  571. **
  572. **  OUTPUT:
  573. **      Data is stored in the buffer.
  574. **      Buffer status is updated.
  575. **      Returns SUCCESS if a record was read successfully.
  576. **      Returns FAILURE if some error occurred.
  577. **
  578. */
  579.  
  580. static uint32       read_record( void )
  581. {
  582.     uint32          bytes;                  /* Number of bytes read         */
  583.  
  584. /*
  585. **  First read the header bytes, because we need to know the length of the
  586. **  record.  If we cannot read any bytes, this must be the end of file.
  587. */
  588.     bytes = fread( (char *)&cas_rec, (int)1, (int)8, cas_file );
  589.     if( bytes == 0 )
  590.         return( FAILURE );
  591.  
  592. /*
  593. **  Found header bytes, compute the record length from the header info.
  594. **  Then read the data portion of the record, if any.
  595. */
  596.     if( bytes != 8 )
  597.     {
  598.         fprintf(stderr, "\nThis is not a valid .cas file, record header damaged.\n");
  599.         return( FAILURE );
  600.     }
  601.     cas_len = (((uint32)cas_rec.cas_len_hi) << 8 ) + cas_rec.cas_len_lo;
  602.     if( cas_len )
  603.     {
  604.         bytes = fread( (char *)cas_rec.cas_data, (int)1, (int)cas_len, cas_file );
  605.         if( bytes != cas_len )
  606.         {
  607.             fprintf(stderr, "\nThis is not a valid .cas file, record damaged.\n");
  608.             return( FAILURE );
  609.         }
  610.     }
  611.     return( SUCCESS );
  612. }
  613.  
  614. /*****************************************************************************
  615. **  NAME:  usage()
  616. **
  617. **  PURPOSE:
  618. **      Display the command line format for the program.
  619. **
  620. **  DESCRIPTION:
  621. **      This function will explain the usage of the program to the user.
  622. **      The program name is taken from the first command line argument.
  623. **
  624. **  INPUT:
  625. **      - The address of the command line, containing the program name.
  626. **
  627. **  OUTPUT:
  628. **      The usage is displayed on the terminal.
  629. **      The function returns nothing.
  630. **
  631. */
  632.  
  633. static void         usage( cmd )
  634. char * cmd;                         /* Program name                     */
  635. {
  636.     char * whoami;      /* For searching program name in command line   */
  637.     char * name;        /* Pointer to actual program name in command    */
  638.     int    len;         /* Length of program name                       */
  639.     int    found_dot;   /* Nonzero if we found a dot in the name        */
  640.  
  641. /*
  642. **  Get program name and print usage message.
  643. **  The complete pathname including extension is part of the first
  644. **  argument as passed by the operating system.
  645. */
  646.     for( whoami = cmd, len = 0, found_dot = 0; *whoami; whoami++ )
  647.     {
  648.         if( *whoami == '.' )
  649.         {
  650.             found_dot = 1;
  651.             continue;
  652.         }
  653.         if( *whoami == '\\' )   /* if this was part of the path, */
  654.         {
  655.             name = whoami + 1;  /* record position */
  656.             len = 0;            /* then restart counting length */
  657.             found_dot = 0;
  658.             continue;
  659.         }
  660.         if( *whoami == ' ' )    /* end of name found            */
  661.             break;
  662.         if( found_dot )         /* skip .exe or .com stuff      */
  663.             continue;
  664.         len++;                  /* Increment program name length */
  665.     }
  666.  
  667. /*
  668. **  Let me explain...
  669. */
  670.     fprintf(stderr, "\nUsage: %.*s [cassette file] [/d] [/w=x] [/t=nnnn] [/m=nnnn] [/s=nnnn]\n", len, name );
  671.     fprintf(stderr, "                               [/b=nnnn] [/l=nnnn] [/i=nnnn]\n");
  672.     fprintf(stderr, "to convert a .cas cassette image file to a .wav file.\n\n");
  673.     fprintf(stderr, "cassette file an Atari classic tape image file.\n");
  674.     fprintf(stderr, "/d            to print diagnostic information.\n");
  675.     fprintf(stderr, "/w=x          to select the waveform of the tone used,\n");
  676.     fprintf(stderr, "              where x is s for sine waves, b for block waves, p for pure tones.\n");
  677.     fprintf(stderr, "/z            to select transition at zero level.\n");
  678.     fprintf(stderr, "/t=nnnn       to generate a test tape only,\n");
  679.     fprintf(stderr, "              where nnnn is the duration in milli-seconds.\n");
  680.     fprintf(stderr, "/m=nnnn       frequency of mark tone in Hertz,\n");
  681.     fprintf(stderr, "              where nnnn is a number around 5327.\n");
  682.     fprintf(stderr, "/s=nnnn       frequency of space tone in Hertz,\n");
  683.     fprintf(stderr, "              where nnnn is a number around 3995.\n");
  684.     fprintf(stderr, "/b=nnnn       fixed baudrate to use,\n");
  685.     fprintf(stderr, "              where nnnn is a number around 600, from 425 to 875.\n");
  686.     fprintf(stderr, "/l=nnnn       fixed length of leader in milli-seconds,\n");
  687.     fprintf(stderr, "              where nnnn is a number around 20000.\n");
  688.     fprintf(stderr, "/i=nnnn       fixed length of Inter Record Gap in milli-seconds,\n");
  689.     fprintf(stderr, "              where nnnn is a number around 250.\n");
  690.     fprintf(stderr, "Refer to the documentation for more information.\n");
  691.  
  692.     return;
  693. }
  694.  
  695. /*****************************************************************************
  696. **  NAME:  write_test_tape()
  697. **
  698. **  PURPOSE:
  699. **      Write data for a test tape to the wav file.
  700. **
  701. **  DESCRIPTION:
  702. **      This function will write test data to the wav file.
  703. **      A test tape consists of only mark and space bits in some test pattern.
  704. **      Use an oscilloscope to view the output of the cassette unit.
  705. **
  706. **  INPUT:
  707. **      - The file pointers and paths are used.
  708. **
  709. **  OUTPUT:
  710. **      The data is written to the wav file.
  711. **      The function returns nothing.
  712. **
  713. */
  714.  
  715. static void         write_test_tape( void )
  716. {
  717.     uint32          sample_count;           /* Count of samples test tape   */
  718.     uint32          samples;                /* Number of samples test tape  */
  719.  
  720. /*
  721. **  We use a fixed filename for test tapes.
  722. */
  723.     fprintf(stderr, "\nProcessing test tape, please wait!\n");
  724.     wav_file = fopen( (char *)"testtape.wav", "wb" );
  725.     if( wav_file == NULL )
  726.     {
  727.         fprintf(stderr, "\nCannot open testtape.wav file!\n");
  728.         cleanup();
  729.         exit( 255 );
  730.     }
  731.  
  732.     if( !header_written )
  733.     {
  734.         write_wav( (char *)"RIFF", (uint32)4L );
  735.         pos_file_size = pos;
  736.         write_wav_number( (uint32)0L, (uint32)4L );
  737.         header_written = TRUE;
  738.     }
  739.     write_wav( (char *)"WAVE", (uint32)4L );
  740.  
  741.     write_wav( (char *)"fmt ", (uint32)4L );
  742.     write_wav_number( (uint32)16L, (uint32)4L ); /* Header size */
  743.  
  744.     write_wav_number( (uint32)1L, (uint32)2L );  /* fmt tag 1 */
  745.     write_wav_number( (uint32)1L, (uint32)2L );  /* channels 1 */
  746.     write_wav_number( (uint32)44100L, (uint32)4L );  /* sample rate 44100 */
  747.     write_wav_number( (uint32)44100L, (uint32)4L );  /* Bytes per second */
  748.     write_wav_number( (uint32)1L, (uint32)2L );  /* Buffer alignment */
  749.  
  750.     write_wav_number( (uint32)8L, (uint32)2L );  /* bits per sample */
  751.  
  752.     write_wav( (char *)"data", (uint32)4L );
  753.     pos_chunk_size = pos;
  754.     write_wav_number( (uint32)0L, (uint32)4L );
  755.  
  756. /*
  757. **  Compute the number of samples to generate.
  758. **  Multiply the number of milli-seconds by the sample rate.
  759. **  The sample rate is per second, so divide by 1000.
  760. */
  761.     samples = ( test_tape * 441 ) / 10;
  762.     sample_count = 0;
  763.  
  764. /*
  765. **  Generate the test pattern.
  766. */
  767.     while( sample_count < samples )
  768.     {
  769.  
  770. /*
  771. **  Alternate mark and space bits.
  772. */
  773. #if 0
  774.         write_wav_bit( FSK_MARK, bitlen );
  775.         sample_count += bitlen;
  776.         write_wav_bit( FSK_SPACE, bitlen );
  777.         sample_count += bitlen;
  778. #endif
  779.  
  780. /*
  781. **  A small piece of silence.
  782. */
  783. #if 0
  784.         for( byte = 0; byte < 881; byte++ )
  785.         {
  786.             write_wav( "\200", 1L );
  787.             sample_count++;
  788.         }
  789. #endif
  790.  
  791. /*
  792. **  Large piece of mark, and alternating space and mark,
  793. **  with elongated space bits.
  794. */
  795. #if 0
  796.         write_wav_bit( FSK_MARK, bitlen * 3 );
  797.         sample_count += bitlen * 3;
  798.         ptr = mark;
  799.         write_wav_bit( FSK_MARK, bitlen * 3 );
  800.         sample_count += bitlen * 3;
  801.         ptr = mark;
  802.         write_wav_bit( FSK_SPACE, bitlen );
  803.         sample_count += bitlen;
  804.         ptr = mark;
  805.         write_wav_bit( FSK_MARK, bitlen - 8);
  806.         sample_count += bitlen;
  807.         ptr = mark;
  808.         write_wav_bit( FSK_SPACE, bitlen + 8);
  809.         sample_count += bitlen;
  810.         ptr = mark;
  811.         write_wav_bit( FSK_MARK, bitlen - 8);
  812.         sample_count += bitlen;
  813.         ptr = mark;
  814.         write_wav_bit( FSK_SPACE, bitlen + 8);
  815.         sample_count += bitlen;
  816.         ptr = mark;
  817.         write_wav_bit( FSK_MARK, bitlen - 8);
  818.         sample_count += bitlen;
  819. #endif
  820.  
  821. /*
  822. **  Large piece of mark, and alternating space and mark,
  823. **  with abrupt change over.
  824. */
  825. #if 0
  826.         ptr = mark;
  827.         write_wav( (char *)&(mark[0]), 414 );
  828.         sample_count += 414;
  829.         write_wav( (char *)&(space[414]), 73 );
  830.         sample_count += 73;
  831.         write_wav( (char *)&(mark[487]), 73 );
  832.         sample_count += 73;
  833.         write_wav( (char *)&(space[560]), 73 );
  834.         sample_count += 73;
  835.         write_wav( (char *)&(mark[633]), 73 );
  836.         sample_count += 73;
  837.         write_wav( (char *)&(space[706]), 73 );
  838.         sample_count += 73;
  839.         write_wav( (char *)&(mark[779]), 73 );
  840.         sample_count += 73;
  841. #endif
  842.  
  843. /*
  844. **  Large piece of mark, and alternating space and mark,
  845. **  with normal change over.
  846. */
  847. #if 1
  848.         ptr = mark;
  849.         table_len = MARK_TABLE_LEN;
  850.         write_wav_bit( FSK_MARK, bitlen * 3 );
  851.         sample_count += bitlen * 3;
  852.         write_wav_bit( FSK_MARK, bitlen * 3 );
  853.         sample_count += bitlen * 3;
  854.         write_wav_bit( FSK_SPACE, bitlen );
  855.         sample_count += bitlen;
  856.         write_wav_bit( FSK_MARK, bitlen );
  857.         sample_count += bitlen;
  858.         write_wav_bit( FSK_SPACE, bitlen );
  859.         sample_count += bitlen;
  860.         write_wav_bit( FSK_MARK, bitlen );
  861.         sample_count += bitlen;
  862.         write_wav_bit( FSK_SPACE, bitlen );
  863.         sample_count += bitlen;
  864.         write_wav_bit( FSK_MARK, bitlen );
  865.         sample_count += bitlen;
  866. #endif
  867.  
  868. /*
  869. **  Large piece of mark, and alternating space and mark,
  870. **  with normal change over and elongated space bits.
  871. */
  872. #if 0
  873.         ptr = mark;
  874.         table_len = MARK_TABLE_LEN;
  875.         write_wav_bit( FSK_MARK, bitlen * 3 );
  876.         sample_count += bitlen * 3;
  877.         write_wav_bit( FSK_MARK, bitlen * 3 );
  878.         sample_count += bitlen * 3;
  879.         write_wav_bit( FSK_SPACE, bitlen + 9 );
  880.         sample_count += bitlen + 9;
  881.         write_wav_bit( FSK_MARK, bitlen - 9);
  882.         sample_count += bitlen - 9;
  883.         write_wav_bit( FSK_SPACE, bitlen + 9);
  884.         sample_count += bitlen + 9;
  885.         write_wav_bit( FSK_MARK, bitlen - 9);
  886.         sample_count += bitlen - 9;
  887.         write_wav_bit( FSK_SPACE, bitlen + 9);
  888.         sample_count += bitlen + 9;
  889.         write_wav_bit( FSK_MARK, bitlen );
  890.         sample_count += bitlen;
  891. #endif
  892.     }
  893.  
  894.     return;
  895. }
  896.  
  897. /*****************************************************************************
  898. **  NAME:  write_wav()
  899. **
  900. **  PURPOSE:
  901. **      Write data to the wav file.
  902. **
  903. **  DESCRIPTION:
  904. **      This function will write the specified buffer to the wav file.
  905. **
  906. **  INPUT:
  907. **      - The address of the data to be written.
  908. **      - The amount of data to be written.
  909. **
  910. **  OUTPUT:
  911. **      The data is written to the wav file.
  912. **      The function returns nothing.
  913. **
  914. */
  915.  
  916. static void         write_wav( buffer, buflen )
  917. char * buffer;                      /* Address of buffer to be written  */
  918. uint32 buflen;                      /* Number of bytes to be written    */
  919. {
  920.     uint32 bytes;       /* Number of bytes actually written             */
  921.  
  922.     bytes = fwrite( buffer, (int)1, (int)buflen, wav_file );
  923.     if( bytes != buflen )
  924.     {
  925.         fprintf(stderr, "\nWrite error on wav file.\n");
  926.         cleanup();
  927.         exit( 255 );
  928.     }
  929.     pos += bytes;
  930.     return;
  931. }
  932.  
  933. /*****************************************************************************
  934. **  NAME:  write_wav_bit()
  935. **
  936. **  PURPOSE:
  937. **      Write a bit or a prwt to the wav file.
  938. **
  939. **  DESCRIPTION:
  940. **      This function will write the specified number of samples to the wav
  941. **      file, representing the selected bit value.
  942. **      The way we make the transition from mark to space or from space to
  943. **      mark depends on the selected format of the waves.
  944. **
  945. **  INPUT:
  946. **      - The bit value to be represented.
  947. **      - The amount of data to be written.
  948. **
  949. **  OUTPUT:
  950. **      The data is written to the wav file.
  951. **      The function returns nothing.
  952. **
  953. */
  954.  
  955. static void         write_wav_bit( bitvalue, samples )
  956. uint32 bitvalue;                    /* The bit value to be represented  */
  957. uint32 samples;                     /* Number of bytes to be written    */
  958. {
  959.     uint32 bytes;                   /* Number of bytes actually written */
  960.     bool   falling;                 /* Level of signal is falling       */
  961.     ubyte  last_value;              /* Last byte value output           */
  962.  
  963. /*
  964. **  Here is where we have to do special things in order to make the
  965. **  selected type of transition from mark to space or from space to mark,
  966. **  if we have a transition at all.  If there is no transition, things
  967. **  are really simple.  If there is a transition, the transition from
  968. **  mark to space is the most important.  Unless we are writing pure
  969. **  tones, the mark tone is always written from the end of the mark table,
  970. **  and the space tone is written from the start of the space table.
  971. **  Unfortunately, sometimes we write a very long mark tone, which is longer
  972. **  than the table.  In this case we will be wrapping around to the start of
  973. **  the table one or more times, so compute where to start at, such that we
  974. **  we arrive at the end of the mark table.
  975. **  With pure tones, we always make a smooth transition.
  976. */
  977.  
  978. /*
  979. **  No bytes written yet.
  980. */
  981.     bytes = 0;
  982.  
  983. /*
  984. **  If only the result counts, we do not care whether or not the wave format
  985. **  looks nice, we just want it to load reliable.  For mark tones, write the
  986. **  tone from the end of the table.  For space tones, write it from the start
  987. **  of the table.  This makes the mark to space transition occur at the zero
  988. **  level.
  989. */
  990.     if( zero_transition )
  991.     {
  992.         if( bitvalue == FSK_MARK )
  993.         {
  994.             if( samples < MARK_TABLE_LEN )
  995.             {
  996.                 ptr = &(mark[MARK_TABLE_LEN - samples]);
  997.                 table_len = samples;
  998.             }
  999.             else
  1000.             {
  1001.                 ptr = &(mark[MARK_TABLE_LEN - (samples % MARK_TABLE_LEN)]);
  1002.                 table_len = samples % MARK_TABLE_LEN;
  1003.             }
  1004.         }
  1005.         else
  1006.         {
  1007.             ptr = space;
  1008.             table_len = SPACE_TABLE_LEN;
  1009.         }
  1010.     } /* end if zero transition */
  1011.     else
  1012.  
  1013. /*
  1014. **  If we are writing pure tones, we must orderly end the current tone
  1015. **  before changing over to the next.
  1016. **  Complete the half period in progress before changing the tone.
  1017. */
  1018.     if( format_pure )
  1019.     {
  1020.  
  1021. /*
  1022. **  When we pass the zero level, change the tone.
  1023. **  Try to make a clean transition from mark to space.
  1024. **  Finish up the last half period of the previous bit.
  1025. **  If the bit is the same, continue with the current tone where we
  1026. **  left off.
  1027. */
  1028.         if( bitvalue != prev_bitvalue )
  1029.         {
  1030.  
  1031. /*
  1032. **  If we are at the start of our generator buffer, no need to do
  1033. **  complicated things, we can simply change to the start of the other
  1034. **  generator tone buffer.
  1035. **  Besides, we would not have a previous value in this case to determine
  1036. **  rising or falling, although we know it is rising.
  1037. */
  1038.             if( ( prev_bitvalue == FSK_MARK ) && ( ptr == mark ) )
  1039.             {
  1040.                 ptr = space;
  1041.                 table_len = SPACE_TABLE_LEN;
  1042.             }
  1043.             else
  1044.             if( ( prev_bitvalue == FSK_SPACE ) && ( ptr == space ) )
  1045.             {
  1046.                 ptr = mark;
  1047.                 table_len = MARK_TABLE_LEN;
  1048.             }
  1049.             else
  1050.  
  1051. /*
  1052. **  Otherwise, figure out whether the signal was rising or falling.
  1053. **  If we just crossed the zero level, we can see whether we are rising
  1054. **  or falling.  If the current value is below the zero level, we are now
  1055. **  falling.  If it is above the zero level, we are now rising.
  1056. */
  1057.             {
  1058.                 if( ( *(ptr - 1) >= ZERO_LEVEL ) && ( *ptr <= ZERO_LEVEL ) )
  1059.                 {
  1060.                     falling = TRUE;
  1061.                 }
  1062.                 else
  1063.                 if( ( *(ptr - 1) <= ZERO_LEVEL ) && ( *ptr >= ZERO_LEVEL ) )
  1064.                 {
  1065.                     falling = FALSE;
  1066.                 }
  1067.                 else
  1068.  
  1069. /*
  1070. **  Since we did not cross the zero level just now, look at the last value.
  1071. **  If it is above the zero level, continue to write samples until we pass
  1072. **  the zero level falling down, otherwise continue to write samples until
  1073. **  we pass the zero level going up.
  1074. */
  1075.                 if( *(ptr - 1) > ZERO_LEVEL )
  1076.                 {
  1077.                     falling = TRUE;
  1078.                     while( *ptr > ZERO_LEVEL )
  1079.                     {
  1080.                         write_wav( (char *)ptr, 1 );
  1081.                         bytes++;
  1082.                         ptr++;
  1083.                         if( --table_len == 0 )
  1084.                             break;
  1085.                     }
  1086.                 }
  1087.                 else
  1088.                 {
  1089.                     falling = FALSE;
  1090.                     while( *ptr < ZERO_LEVEL )
  1091.                     {
  1092.                         write_wav( (char *)ptr, 1 );
  1093.                         bytes++;
  1094.                         ptr++;
  1095.                         if( --table_len == 0 )
  1096.                             break;
  1097.                     }
  1098.                 }
  1099.  
  1100. /*
  1101. **  At this point, we finished the last half period of the previous
  1102. **  tone.  Now switch tone.  Make sure we are going in the same direction
  1103. **  as the previous tone, either falling or rising.
  1104. **  This means that if we need to be falling, we must move ahead until
  1105. **  we are.  The tables start out rising.
  1106. */
  1107.                 if( bitvalue == FSK_MARK )
  1108.                 {
  1109.                     ptr = mark;
  1110.                     table_len = MARK_TABLE_LEN;
  1111.                 }
  1112.                 else
  1113.                 {
  1114.                     ptr = space;
  1115.                     table_len = SPACE_TABLE_LEN;
  1116.                 }
  1117.  
  1118. /*
  1119. **  If falling, search for the zero crossing in the other table.
  1120. */
  1121.                 if( falling )
  1122.                 {
  1123.                     ptr++;
  1124.                     table_len--;
  1125.                     for( ; table_len; ptr++, table_len-- )
  1126.                     {
  1127.                         if( *ptr <= ZERO_LEVEL )
  1128.                             break;
  1129.                     }
  1130.                 }
  1131.             } /* end else if at start of buffer */
  1132.         } /* end if bit value changed */
  1133.     } /* end if pure tones */
  1134.  
  1135.     else
  1136.  
  1137. /*
  1138. **  If we are writing normal sine waves, change from one sine wave to
  1139. **  the other.  Do so by finding the corresponding value in the other table,
  1140. **  and continue writing data from the other table.
  1141. */
  1142.     if( format_sine )
  1143.     {
  1144.         if( bitvalue != prev_bitvalue )
  1145.         {
  1146.  
  1147. /*
  1148. **  Check for start of buffer.
  1149. */
  1150.             if( ( prev_bitvalue == FSK_MARK ) && ( ptr == mark ) )
  1151.             {
  1152.                 ptr = space;
  1153.                 table_len = SPACE_TABLE_LEN;
  1154.             }
  1155.             else
  1156.             if( ( prev_bitvalue == FSK_SPACE ) && ( ptr == space ) )
  1157.             {
  1158.                 ptr = mark;
  1159.                 table_len = MARK_TABLE_LEN;
  1160.             }
  1161.             else
  1162.  
  1163. /*
  1164. **  Compare the current value to the last value.  If it is smaller, we
  1165. **  are falling.  If it is larger, we are rising.  If it is the same, we
  1166. **  must be at the top or bottom of the sine wave, and we are then moving
  1167. **  away from that.
  1168. */
  1169.             {
  1170.                 last_value = *(ptr - 1);
  1171.  
  1172. #if 0
  1173.  
  1174. /*
  1175. **  If the space value was larger than any value in the mark table,
  1176. **  we will never find the correct value, so limit it to the top value.
  1177. */
  1178.                 if( last_value > 192 )
  1179.                 {
  1180.                     falling = TRUE;
  1181.                     last_value = 192;
  1182.                 }
  1183.                 else
  1184.                 if( last_value < 64 )
  1185.                 {
  1186.                     falling = FALSE;
  1187.                     last_value = 64;
  1188.                 }
  1189.                 else
  1190.  
  1191. #endif
  1192.  
  1193.                 if( last_value > *ptr )
  1194.                 {
  1195.                     falling = TRUE;
  1196.                 }
  1197.                 else
  1198.                 if( last_value < *ptr )
  1199.                 {
  1200.                     falling = FALSE;
  1201.                 }
  1202.                 else
  1203.  
  1204. /*
  1205. **  Values are the same, moving away from top, determine which top.
  1206. */
  1207.                 {
  1208.                     if( *ptr > ZERO_LEVEL )
  1209.                         falling = TRUE;
  1210.                     else
  1211.                         falling = FALSE;
  1212.                 }
  1213.  
  1214. /*
  1215. **  Now that we know whether we are rising or falling, find the value we
  1216. **  wrote last, but this time in the buffer for the other frequency, and
  1217. **  find it either falling or rising, whatever it was we were doing.
  1218. */
  1219.                 if( bitvalue == FSK_MARK )
  1220.                 {
  1221.                     ptr = mark + 1;
  1222.                     table_len = MARK_TABLE_LEN - 1;
  1223.                 }
  1224.                 else
  1225.                 {
  1226.                     ptr = space + 1;
  1227.                     table_len = SPACE_TABLE_LEN - 1;
  1228.                 }
  1229.  
  1230. /*
  1231. **  Search for the value in the other table.
  1232. */
  1233.                 for( ; table_len; ptr++, table_len-- )
  1234.                 {
  1235.                     if( *ptr == last_value )
  1236.                     {
  1237.                         if( falling )
  1238.                         {
  1239.                             ptr++;
  1240.                             table_len--;
  1241.                             if( table_len == 0 )
  1242.                                 break;
  1243.                             if( *ptr < last_value )
  1244.                                 break;
  1245.                         }
  1246.                         else
  1247.                         {
  1248.                             ptr++;
  1249.                             table_len--;
  1250.                             if( table_len == 0 )
  1251.                                 break;
  1252.                             if( *ptr > last_value )
  1253.                                 break;
  1254.                         }
  1255.                     } /* end if matching value found */
  1256.                 } /* end search for matching value and direction */
  1257.             } /* end else if at start of buffer */
  1258.         } /* end if bit value changed */
  1259.     } /* end if sine wave */
  1260.  
  1261.     else
  1262.  
  1263. /*
  1264. **  Nothing left but square waves.  We cannot really make them smooth.
  1265. **  We do make sure that at least the level changes to the opposite,
  1266. **  so that the length of the first period is correct.
  1267. */
  1268.     if( format_square )
  1269.     {
  1270.         if( bitvalue == FSK_MARK )
  1271.         {
  1272.             if( *ptr > ZERO_LEVEL )
  1273.             {
  1274.                 ptr = mark;
  1275.                 table_len = MARK_TABLE_LEN;
  1276.                 while( *ptr > ZERO_LEVEL )
  1277.                 {
  1278.                     ptr++;
  1279.                     table_len--;
  1280.                 }
  1281.             }
  1282.             else
  1283.             {
  1284.                 ptr = mark;
  1285.                 table_len = MARK_TABLE_LEN;
  1286.             }
  1287.         } /* end if mark */
  1288.         else
  1289.         {
  1290.             if( *ptr > ZERO_LEVEL )
  1291.             {
  1292.                 ptr = space;
  1293.                 table_len = SPACE_TABLE_LEN;
  1294.                 while( *ptr > ZERO_LEVEL )
  1295.                 {
  1296.                     ptr++;
  1297.                     table_len--;
  1298.                 }
  1299.             }
  1300.             else
  1301.             {
  1302.                 ptr = space;
  1303.                 table_len = SPACE_TABLE_LEN;
  1304.             }
  1305.         } /* end else if mark */
  1306.     } /* end if square waves */
  1307.  
  1308. /*
  1309. **  We are now pointing to the correct spot in the buffer.
  1310. **  Write the requested number of samples.  Deduct the number of samples
  1311. **  we used to complete the previous tone.
  1312. */
  1313.     if( samples > bytes )
  1314.     {
  1315.         while( samples - bytes > table_len )
  1316.         {
  1317.             write_wav( (char *)ptr, table_len );
  1318.             bytes += table_len;
  1319.  
  1320.             if( bitvalue == FSK_MARK )
  1321.             {
  1322.                 ptr = mark;
  1323.                 table_len = MARK_TABLE_LEN;
  1324.             }
  1325.             else
  1326.             {
  1327.                 ptr = space;
  1328.                 table_len = SPACE_TABLE_LEN;
  1329.             }
  1330.         }
  1331.         write_wav( (char *)ptr, samples - bytes );
  1332.         ptr += ( samples - bytes );
  1333.         table_len -= ( samples - bytes );
  1334.     }
  1335.  
  1336.     prev_bitvalue = bitvalue;
  1337.  
  1338.     if( table_len == 0 )
  1339.     {
  1340.         if( bitvalue == FSK_MARK )
  1341.         {
  1342.             ptr = mark;
  1343.             table_len = MARK_TABLE_LEN;
  1344.         }
  1345.         else
  1346.         {
  1347.             ptr = space;
  1348.             table_len = SPACE_TABLE_LEN;
  1349.         }
  1350.     }
  1351. }
  1352.  
  1353. /*****************************************************************************
  1354. **  NAME:  write_wav_number()
  1355. **
  1356. **  PURPOSE:
  1357. **      Write a number to the wav file.
  1358. **
  1359. **  DESCRIPTION:
  1360. **      This function will write the specified number to the wav file.
  1361. **
  1362. **  INPUT:
  1363. **      - The number to be written.
  1364. **      - The amount of data to be written.
  1365. **
  1366. **  OUTPUT:
  1367. **      The data is written to the wav file.
  1368. **      The function returns nothing.
  1369. **
  1370. */
  1371.  
  1372. static void         write_wav_number( value, buflen )
  1373. uint32 value;                       /* The number to be written         */
  1374. uint32 buflen;                      /* Number of bytes to be written    */
  1375. {
  1376.     number[0] = value;
  1377.     number[1] = value >> 8;
  1378.     number[2] = value >> 16;
  1379.     number[3] = value >> 24;
  1380.     write_wav( (char *)number, buflen );
  1381. }
  1382.  
  1383. /*****************************************************************************
  1384. ==  EXPORTED FUNCTIONS
  1385. *****************************************************************************/
  1386.  
  1387. /*****************************************************************************
  1388. **  NAME:  MAIN()
  1389. **
  1390. **  PURPOSE:
  1391. **      An entry point for testing or running this utility.
  1392. **
  1393. **  DESCRIPTION:
  1394. **      Prompt for the file to open and then go process it.
  1395. **
  1396. **  INPUT:
  1397. **      argc and argv.
  1398. **
  1399. **  OUTPUT:
  1400. **      Returns an int as it should.
  1401. **
  1402. */
  1403. int                 main( argc, argv )
  1404. int                 argc;               /* Command line argument count  */
  1405. char              * argv[];             /* Command line argument ptrs   */
  1406. {
  1407.     ubyte           answer;                 /* Response to yes/no question  */
  1408.     uint32          arg_ndx;                /* Argument number index        */
  1409.     uint32          arg_no;                 /* Argument number              */
  1410.     uint32          byte;                   /* Byte index                   */
  1411.     uint32          wrk_ndx;                /* Work index                   */
  1412.     bool            end_of_str;             /* Null terminator seen?        */
  1413.     ubyte           input_path[PATH_LEN];   /* Input cas file spec          */
  1414.     uint32          len_chunk;              /* Chunck length                */
  1415.     uint32          len_file;               /* File length                  */
  1416.     ubyte           wav_path[PATH_LEN];     /* Output wave file spec        */
  1417.     ubyte           buf[BUF_LEN];           /* Buffer string                */
  1418.     double          rad;                    /* Radians intermediate value   */
  1419.     double          rad_mark;               /* Radians intermediate value   */
  1420.     double          rad_space;              /* Radians intermediate value   */
  1421.     uint32          stat;                   /* Status from function         */
  1422.     ubyte           proceed;                /* Proceed with conversion      */
  1423.  
  1424. /*
  1425. **  Allocate buffer space for the tone generators.
  1426. */
  1427.     mark = (ubyte *)malloc((unsigned long)MARK_TABLE_LEN * sizeof( ubyte ) );
  1428.     space = (ubyte *)malloc((unsigned long)SPACE_TABLE_LEN * sizeof( ubyte ) );
  1429.  
  1430.     if( !mark || !space )
  1431.     {
  1432.         fprintf( stderr, "\nCannot allocate buffer, insufficient memory.\n" );
  1433.         cleanup();
  1434.         exit( 255 );
  1435.     }
  1436.  
  1437. /*
  1438. **  Process command line arguments.
  1439. **  We do not treat the options switch as an argument.  It may be placed
  1440. **  anywhere on the command line.  So we have to count the arguments ourselves
  1441. **  so that we know what argument we are processing.
  1442. */
  1443.     arg_no = 0;
  1444.     diagnostics = FALSE;
  1445.     test_tape = 0;
  1446.     baudrate = 600;
  1447.     baudrate_fixed = FALSE;
  1448.     leader = 0;
  1449.     irg = 0;
  1450.     mark_tone = FSK_TONE_MARK;
  1451.     space_tone = FSK_TONE_SPACE;
  1452.     table_len = MARK_TABLE_LEN;
  1453.     recno = 0;
  1454.     format_pure = FALSE;
  1455.     format_sine = TRUE;
  1456.     format_square = FALSE;
  1457.     zero_transition = FALSE;
  1458.  
  1459.     for( arg_ndx = 1; arg_ndx < argc; arg_ndx++ )
  1460.     {
  1461.  
  1462. /*
  1463. **  If we encounter the options switch, process the options.
  1464. **  The options must start with a slash.
  1465. */
  1466.         if( argv[arg_ndx][0] == '/' )
  1467.         {
  1468.  
  1469.             for( wrk_ndx = 1; argv[arg_ndx][wrk_ndx]; wrk_ndx++ )
  1470.             {
  1471.  
  1472. /*
  1473. **  If the user is confused, seeking help, she/he should read the * manual.
  1474. **  We can give them a hint though.
  1475. */
  1476.                 if( argv[arg_ndx][wrk_ndx] == '?' )
  1477.                 {
  1478.                     usage( argv[0] );
  1479.                     exit( 0 );
  1480.                 }
  1481.  
  1482. /*
  1483. **  The /d option selects the diagnostics output.
  1484. */
  1485.                 if( toupper( argv[arg_ndx][wrk_ndx] ) == 'D' )
  1486.                 {
  1487.                     diagnostics = TRUE;
  1488.                     break;
  1489.                 }
  1490.  
  1491. /*
  1492. **  The /z option selects the transition at the zero level.
  1493. */
  1494.                 if( toupper( argv[arg_ndx][wrk_ndx] ) == 'Z' )
  1495.                 {
  1496.                     zero_transition = TRUE;
  1497.                     break;
  1498.                 }
  1499.  
  1500. /*
  1501. **  The /w option selects the wave format.
  1502. */
  1503.                 if( toupper( argv[arg_ndx][wrk_ndx] ) == 'W' )
  1504.                 {
  1505.                     while( argv[arg_ndx][++wrk_ndx] )
  1506.                     {
  1507.                         if( toupper( argv[arg_ndx][wrk_ndx] ) == 'S' )
  1508.                         {
  1509.                             format_pure = FALSE;
  1510.                             format_sine = TRUE;
  1511.                             format_square = FALSE;
  1512.                         }
  1513.                         if( toupper( argv[arg_ndx][wrk_ndx] ) == 'B' )
  1514.                         {
  1515.                             format_pure = FALSE;
  1516.                             format_sine = FALSE;
  1517.                             format_square = TRUE;
  1518.                         }
  1519.                         if( toupper( argv[arg_ndx][wrk_ndx] ) == 'P' )
  1520.                         {
  1521.                             format_pure = TRUE;
  1522.                             format_sine = TRUE;
  1523.                             format_square = FALSE;
  1524.                         }
  1525.                     }
  1526.                     break;
  1527.                 }
  1528.  
  1529. /*
  1530. **  The /t option selects a test tape output.
  1531. */
  1532.                 if( toupper( argv[arg_ndx][wrk_ndx] ) == 'T' )
  1533.                 {
  1534.                     test_tape = 0;
  1535.                     while( argv[arg_ndx][++wrk_ndx] )
  1536.                     {
  1537.                         if( ( argv[arg_ndx][wrk_ndx] >= '0' ) &&
  1538.                             ( argv[arg_ndx][wrk_ndx] <= '9' ) )
  1539.                         {
  1540.                             test_tape *= 10;
  1541.                             test_tape += argv[arg_ndx][wrk_ndx] - '0';
  1542.                         }
  1543.                     }
  1544.                     break;
  1545.                 }
  1546.  
  1547. /*
  1548. **  The /m option selects the mark tone frequency.
  1549. **  The format of this switch is /m=nnnn where nnnn is a numeric value
  1550. **  that should be around 5327 Hertz.  We accept any number the user enters
  1551. **  though.
  1552. */
  1553.                 if( toupper( argv[arg_ndx][wrk_ndx] ) == 'M' )
  1554.                 {
  1555.                     mark_tone = 0;
  1556.                     while( argv[arg_ndx][++wrk_ndx] )
  1557.                     {
  1558.                         if( ( argv[arg_ndx][wrk_ndx] >= '0' ) &&
  1559.                             ( argv[arg_ndx][wrk_ndx] <= '9' ) )
  1560.                         {
  1561.                             mark_tone *= 10;
  1562.                             mark_tone += argv[arg_ndx][wrk_ndx] - '0';
  1563.                         }
  1564.                     }
  1565.                     break;
  1566.                 }
  1567.  
  1568. /*
  1569. **  The /s option selects the space tone frequency.
  1570. **  The format of this switch is /s=nnnn where nnnn is a numeric value
  1571. **  that should be around 3995 Hertz.  We accept any number the user enters
  1572. **  though.
  1573. */
  1574.                 if( toupper( argv[arg_ndx][wrk_ndx] ) == 'S' )
  1575.                 {
  1576.                     space_tone = 0;
  1577.                     while( argv[arg_ndx][++wrk_ndx] )
  1578.                     {
  1579.                         if( ( argv[arg_ndx][wrk_ndx] >= '0' ) &&
  1580.                             ( argv[arg_ndx][wrk_ndx] <= '9' ) )
  1581.                         {
  1582.                             space_tone *= 10;
  1583.                             space_tone += argv[arg_ndx][wrk_ndx] - '0';
  1584.                         }
  1585.                     }
  1586.                     break;
  1587.                 }
  1588.  
  1589. /*
  1590. **  The /b option selects the baudrate.
  1591. **  The format of this switch is /b=nnnn where nnnn is a numeric value
  1592. **  that should be around 600 baud.  We accept any number the user enters
  1593. **  though.
  1594. */
  1595.                 if( toupper( argv[arg_ndx][wrk_ndx] ) == 'B' )
  1596.                 {
  1597.                     baudrate = 0;
  1598.                     baudrate_fixed = TRUE;
  1599.                     while( argv[arg_ndx][++wrk_ndx] )
  1600.                     {
  1601.                         if( ( argv[arg_ndx][wrk_ndx] >= '0' ) &&
  1602.                             ( argv[arg_ndx][wrk_ndx] <= '9' ) )
  1603.                         {
  1604.                             baudrate *= 10;
  1605.                             baudrate += argv[arg_ndx][wrk_ndx] - '0';
  1606.                         }
  1607.                     }
  1608.                     break;
  1609.                 }
  1610.  
  1611. /*
  1612. **  The /l option selects the length of the leader.
  1613. **  The format of this switch is /l=nnnn where nnnn is a numeric value
  1614. **  that should be around 20000 milli-seconds.  We accept any number the user
  1615. **  enters though.
  1616. */
  1617.                 if( toupper( argv[arg_ndx][wrk_ndx] ) == 'L' )
  1618.                 {
  1619.                     leader = 0;
  1620.                     while( argv[arg_ndx][++wrk_ndx] )
  1621.                     {
  1622.                         if( ( argv[arg_ndx][wrk_ndx] >= '0' ) &&
  1623.                             ( argv[arg_ndx][wrk_ndx] <= '9' ) )
  1624.                         {
  1625.                             leader *= 10;
  1626.                             leader += argv[arg_ndx][wrk_ndx] - '0';
  1627.                         }
  1628.                     }
  1629.                     break;
  1630.                 }
  1631.  
  1632. /*
  1633. **  The /i option selects the length of inter record gaps.
  1634. **  The format of this switch is /i=nnnn where nnnn is a numeric value
  1635. **  that should be around 250 milli-seconds.  We accept any number the user
  1636. **  enters though.
  1637. */
  1638.                 if( toupper( argv[arg_ndx][wrk_ndx] ) == 'I' )
  1639.                 {
  1640.                     irg = 0;
  1641.                     while( argv[arg_ndx][++wrk_ndx] )
  1642.                     {
  1643.                         if( ( argv[arg_ndx][wrk_ndx] >= '0' ) &&
  1644.                             ( argv[arg_ndx][wrk_ndx] <= '9' ) )
  1645.                         {
  1646.                             irg *= 10;
  1647.                             irg += argv[arg_ndx][wrk_ndx] - '0';
  1648.                         }
  1649.                     }
  1650.                     break;
  1651.                 }
  1652.  
  1653. /*
  1654. **  Ignore other options.
  1655. */
  1656.                 fprintf(stderr,"\nOption %c invalid.\n", argv[arg_ndx][wrk_ndx] );
  1657.                 break;
  1658.             } /* end for all characters after options switch */
  1659.  
  1660. /*
  1661. **  No further processing for the options switches.
  1662. */
  1663.             continue;
  1664.         } /* end if options switch */
  1665.         arg_no++;
  1666.  
  1667. /*
  1668. **  First argument is the file spec.
  1669. */
  1670.         if( arg_no == 1 )
  1671.         {
  1672.             for ( wrk_ndx = 0, end_of_str = FALSE;
  1673.                 wrk_ndx < PATH_LEN; wrk_ndx++ )
  1674.             {
  1675.                 if ( argv[arg_ndx][wrk_ndx] == '\0' ) /* End of argument string?            */
  1676.                     end_of_str = TRUE;
  1677.                 if ( end_of_str )
  1678.                     input_path[wrk_ndx] = '\0';
  1679.                 else
  1680.                     input_path[wrk_ndx] = toupper( argv[arg_ndx][wrk_ndx] );
  1681.             }
  1682.  
  1683.             cas_file = fopen( (char *)input_path, "rb" );
  1684.             if( cas_file == NULL )
  1685.             {
  1686.                 fprintf(stderr, "Cannot open cassette image file %s\n", input_path);
  1687.                 exit( 255 );
  1688.             }
  1689.         }
  1690.     } /* end for all command line arguments */
  1691.  
  1692. /*
  1693. **  If there is no filename on the command line, ask for it.
  1694. */
  1695.     if( arg_no == 0 && !test_tape )
  1696.     {
  1697.  
  1698. /*
  1699. **  Open hailing frequencies.
  1700. **  No command line arguments, so ask what it is we have to do.
  1701. */
  1702.         printf( "\n\nClassic Atari cassette tape recovery version April 26, 1999\n" );
  1703.         printf( "\n\nCopyright 1998, 1999 by Ernest R. Schreurs\n" );
  1704.         printf( "\n\nAll rights reserved\n" );
  1705.  
  1706.  
  1707.         while( TRUE )                       /* until terminated by control Z*/
  1708.         {
  1709.             printf( "\nEnter ^Z or hit Control Z to terminate\n" );
  1710.  
  1711.             do                              /* until .cas file entered    */
  1712.             {
  1713.                 printf("\nEnter .cas file to be converted : ");
  1714.                 GET_BUF();
  1715.  
  1716.                 for ( wrk_ndx = 0, end_of_str = FALSE;
  1717.                     wrk_ndx < PATH_LEN; wrk_ndx++ )
  1718.                 {
  1719.                     if ( wrk_ndx < BUF_LEN )
  1720.                     {
  1721.                         if ( buf[wrk_ndx] == '\n' ) /* End of inputted string?      */
  1722.                             end_of_str = TRUE;
  1723.                         if ( buf[wrk_ndx] == '\0' ) /* Overkill, End marked by \n   */
  1724.                             end_of_str = TRUE;
  1725.                         if ( end_of_str )
  1726.                             input_path[wrk_ndx] = '\0';
  1727.                         else
  1728.                             input_path[wrk_ndx] = toupper( buf[wrk_ndx] );
  1729.                     }
  1730.                 }
  1731.             } while ( input_path[0] == ' ' );
  1732.  
  1733.             do                              /* until answer is Y or N       */
  1734.             {
  1735.                 printf("\nConvert file %s\n", input_path);
  1736.                 printf("\nIs this correct [Y]es or N)o : ");
  1737.                 GET_BUF();
  1738.                 proceed = toupper( buf[0] );
  1739.  
  1740. /*
  1741. **  If blank, default is correct
  1742. */
  1743.                 if ( proceed == '\n' )
  1744.                     proceed = 'Y';
  1745.  
  1746.             } while ( proceed != 'Y' && proceed != 'N' );
  1747.  
  1748.             if ( proceed == 'N' )
  1749.                 continue;
  1750.  
  1751.             cas_file = fopen( (char *)input_path, "rb" );
  1752.             if( cas_file == NULL )
  1753.             {
  1754.                 fprintf(stderr, "Cannot open cassette image file\n");
  1755.                 continue;
  1756.             }
  1757.             break;
  1758.         } /* end while need a valid filename */
  1759.  
  1760.         do                              /* until answer is Y or N       */
  1761.         {
  1762.             printf("\nPrint diagnostic data [Y]es or N)o : ");
  1763.             GET_BUF();
  1764.             answer = toupper( buf[0] );
  1765.  
  1766. /*
  1767. **  If blank, default is correct
  1768. */
  1769.             if ( answer == '\n' )
  1770.                 answer = 'Y';
  1771.         } while ( answer != 'Y' && answer != 'N' );
  1772.  
  1773.         diagnostics = ( answer == 'Y' ) ? TRUE : FALSE;
  1774.  
  1775. /*
  1776. **  Ask for the wave format.
  1777. */
  1778.         format_pure = FALSE;
  1779.         format_sine = FALSE;
  1780.         format_square = FALSE;
  1781.         do                              /* until answer is S or B or P */
  1782.         {
  1783.             printf("\nDo you want s)ine waves, b)lock waves or p)ure waves? [s]: ");
  1784.             GET_BUF();
  1785.             answer = toupper( buf[0] );
  1786.  
  1787. /*
  1788. **  If blank, default is block waves
  1789. */
  1790.             if ( answer == '\n' )
  1791.                 answer = 'S';
  1792.  
  1793.         } while ( (answer != 'S') && (answer != 'B') && (answer != 'P') );
  1794.  
  1795.         if( answer == 'S' )
  1796.         {
  1797.             format_pure = FALSE;
  1798.             format_sine = TRUE;
  1799.             format_square = FALSE;
  1800.         }
  1801.         if( answer == 'B' )
  1802.         {
  1803.             format_pure = FALSE;
  1804.             format_sine = FALSE;
  1805.             format_square = TRUE;
  1806.         }
  1807.         if( answer == 'P' )
  1808.         {
  1809.             format_pure = TRUE;
  1810.             format_sine = TRUE;
  1811.             format_square = FALSE;
  1812.         }
  1813.  
  1814.         do                              /* until answer is Y or N       */
  1815.         {
  1816.             printf("\nUse space/mark transition at zero level Y)es or [N]o : ");
  1817.             GET_BUF();
  1818.             answer = toupper( buf[0] );
  1819.  
  1820. /*
  1821. **  If blank, default is no
  1822. */
  1823.             if ( answer == '\n' )
  1824.                 answer = 'N';
  1825.  
  1826.         } while ( answer != 'Y' && answer != 'N' );
  1827.  
  1828.         zero_transition = ( answer == 'Y' ) ? TRUE : FALSE;
  1829.  
  1830. /*
  1831. **  Ask for the mark tone frequency.
  1832. */
  1833.         printf("\nEnter mark frequency [5327]: ");
  1834.         GET_BUF();
  1835.         mark_tone = 0;
  1836.  
  1837.         for( wrk_ndx = 0; wrk_ndx < BUF_LEN; wrk_ndx++ )
  1838.         {
  1839.             if ( buf[wrk_ndx] == '\n' ) /* End of inputted string?      */
  1840.                 break;
  1841.             if ( buf[wrk_ndx] == '\0' ) /* Overkill, End marked by \n   */
  1842.                 break;
  1843.             if( ( buf[wrk_ndx] >= '0' ) &&
  1844.                 ( buf[wrk_ndx] <= '9' ) )
  1845.             {
  1846.                 mark_tone *= 10;
  1847.                 mark_tone += buf[wrk_ndx] - '0';
  1848.             }
  1849.         }
  1850.         if( mark_tone == 0 )
  1851.             mark_tone = FSK_TONE_MARK;
  1852.  
  1853. /*
  1854. **  Ask for the space tone frequency.
  1855. */
  1856.         printf("\nEnter space frequency [3995]: ");
  1857.         GET_BUF();
  1858.         space_tone = 0;
  1859.  
  1860.         for( wrk_ndx = 0; wrk_ndx < BUF_LEN; wrk_ndx++ )
  1861.         {
  1862.             if ( buf[wrk_ndx] == '\n' ) /* End of inputted string?      */
  1863.                 break;
  1864.             if ( buf[wrk_ndx] == '\0' ) /* Overkill, End marked by \n   */
  1865.                 break;
  1866.             if( ( buf[wrk_ndx] >= '0' ) &&
  1867.                 ( buf[wrk_ndx] <= '9' ) )
  1868.             {
  1869.                 space_tone *= 10;
  1870.                 space_tone += buf[wrk_ndx] - '0';
  1871.             }
  1872.         }
  1873.         if( space_tone == 0 )
  1874.             space_tone = FSK_TONE_SPACE;
  1875.  
  1876. /*
  1877. **  Ask for a fixed baudrate.
  1878. */
  1879.         printf("\nEnter fixed baudrate if desired 425 - 875 : ");
  1880.         GET_BUF();
  1881.         baudrate = 0;
  1882.  
  1883.         for( wrk_ndx = 0; wrk_ndx < BUF_LEN; wrk_ndx++ )
  1884.         {
  1885.             if ( buf[wrk_ndx] == '\n' ) /* End of inputted string?      */
  1886.                 break;
  1887.             if ( buf[wrk_ndx] == '\0' ) /* Overkill, End marked by \n   */
  1888.                 break;
  1889.             if( ( buf[wrk_ndx] >= '0' ) &&
  1890.                 ( buf[wrk_ndx] <= '9' ) )
  1891.             {
  1892.                 baudrate *= 10;
  1893.                 baudrate += buf[wrk_ndx] - '0';
  1894.             }
  1895.         }
  1896.         if( baudrate == 0 )
  1897.             baudrate = 600;
  1898.         else
  1899.             baudrate_fixed = TRUE;
  1900.  
  1901. /*
  1902. **  Ask for the fixed length of the leader.
  1903. */
  1904.         printf("\nLength of leader if fixed length in milli-seconds : ");
  1905.         GET_BUF();
  1906.         leader = 0;
  1907.  
  1908.         for( wrk_ndx = 0; wrk_ndx < BUF_LEN; wrk_ndx++ )
  1909.         {
  1910.             if ( buf[wrk_ndx] == '\n' ) /* End of inputted string?      */
  1911.                 break;
  1912.             if ( buf[wrk_ndx] == '\0' ) /* Overkill, End marked by \n   */
  1913.                 break;
  1914.             if( ( buf[wrk_ndx] >= '0' ) &&
  1915.                 ( buf[wrk_ndx] <= '9' ) )
  1916.             {
  1917.                 leader *= 10;
  1918.                 leader += buf[wrk_ndx] - '0';
  1919.             }
  1920.         }
  1921.  
  1922. /*
  1923. **  Ask for the fixed length of the irg.
  1924. */
  1925.         printf("\nLength of Inter Record Gap if fixed length in milli-seconds : ");
  1926.         GET_BUF();
  1927.         irg = 0;
  1928.  
  1929.         for( wrk_ndx = 0; wrk_ndx < BUF_LEN; wrk_ndx++ )
  1930.         {
  1931.             if ( buf[wrk_ndx] == '\n' ) /* End of inputted string?      */
  1932.                 break;
  1933.             if ( buf[wrk_ndx] == '\0' ) /* Overkill, End marked by \n   */
  1934.                 break;
  1935.             if( ( buf[wrk_ndx] >= '0' ) &&
  1936.                 ( buf[wrk_ndx] <= '9' ) )
  1937.             {
  1938.                 irg *= 10;
  1939.                 irg += buf[wrk_ndx] - '0';
  1940.             }
  1941.         }
  1942.  
  1943.     } /* end else if command line arguments */
  1944.  
  1945. /*
  1946. **  Compute the sine value for all sample positions.
  1947. **  The mark tone is 5327 Hertz.  One period is 2 PI radians,
  1948. **  One second contains 5327 periods.  We have 44,100 samples in one second.
  1949. **  To evenly divide these 5327 * 2 PI radians over 44,100 samples, we
  1950. **  have to divide by 44,100.  To get the radians value, multiply by the
  1951. **  sample position number.  Similar computations are done for the space tone.
  1952. **  Convert the sine value to a PCM value with proper audio volume by
  1953. **  multiplying it by 64.
  1954. **  The center of the PCM values is at 128, thus we add 128.
  1955. */
  1956.     rad = (double)mark_tone * 2.0 * PI / MARK_TABLE_LEN;
  1957.     for( byte = 0; byte < MARK_TABLE_LEN; byte++ )
  1958.     {
  1959.         mark[byte] = sin( rad * byte ) * 64 + ZERO_LEVEL;
  1960.  
  1961.         if( format_square )
  1962.         {
  1963.             if( mark[byte] >= ZERO_LEVEL )
  1964.                 mark[byte] = 192;
  1965.             else
  1966.                 mark[byte] = 64;
  1967.         }
  1968.  
  1969.     }
  1970.     rad = (double)space_tone * 2.0 * PI / SPACE_TABLE_LEN;
  1971.     for( byte = 0; byte < SPACE_TABLE_LEN; byte++ )
  1972.     {
  1973.         space[byte] = sin( rad * byte ) * 64 + ZERO_LEVEL;
  1974.  
  1975.         if( format_square )
  1976.         {
  1977.             if( space[byte] >= ZERO_LEVEL )
  1978.                 space[byte] = 128;
  1979.             else
  1980.                 space[byte] = 64;
  1981.         }
  1982.  
  1983.     }
  1984.  
  1985. /*
  1986. **  Initialize the pointer to the table.
  1987. */
  1988.     bytelen = ( 44100L * 10 ) / baudrate;
  1989.     bitlen = 44100L / baudrate;
  1990.  
  1991. #if 0
  1992.  
  1993.     bit_stretch = 9;
  1994.     if( zero_transition && format_square )
  1995.         bit_stretch = 0;
  1996.  
  1997. #endif
  1998.  
  1999.     header_written = FALSE;
  2000.     prev_bitvalue = FSK_MARK;
  2001.     ptr = mark;
  2002.     table_len = MARK_TABLE_LEN;
  2003.  
  2004. /*
  2005. **  If we must write a test-tape, do so, and then quit.
  2006. */
  2007.     if( test_tape )
  2008.     {
  2009.         write_test_tape();
  2010.     } /* end if test tape */
  2011.     else
  2012.  
  2013. /*
  2014. **  Generate a wave file based on the .cas file.
  2015. */
  2016.     {
  2017.  
  2018. /*
  2019. **  Process the header of the .cas file.
  2020. */
  2021.         stat = process_header();
  2022.         if( stat == FAILURE )
  2023.         {
  2024.             cleanup();
  2025.             exit( 255 );
  2026.         }
  2027.  
  2028.         PRINT( ("File : %s\n", input_path ) );
  2029.  
  2030.         memcpy( wav_path, input_path, PATH_LEN );
  2031.  
  2032. /*
  2033. **  Find the dot and replace by or add .wav extension.
  2034. */
  2035.         wrk_ndx = STRLEN(wav_path);
  2036.         for( ;; )
  2037.         {
  2038.             if( wav_path[wrk_ndx] == '.' )
  2039.             {
  2040.                 memcpy( &(wav_path[wrk_ndx]), ".wav", 5 );
  2041.                 break;
  2042.             }
  2043.             if( ( wrk_ndx == 0 ) ||
  2044.                 ( wav_path[wrk_ndx] == '/' ) ||
  2045.                 ( wav_path[wrk_ndx] == '\\' ) )
  2046.             {
  2047.                 memcpy( &(wav_path[STRLEN(wav_path)]), ".wav", 5 );
  2048.                 break;
  2049.             }
  2050.             wrk_ndx--;
  2051.         }
  2052.  
  2053.         wav_file = fopen( (char *)wav_path, "wb" );
  2054.         if( wav_file == NULL )
  2055.         {
  2056.             fprintf(stderr, "\nCannot open .wav file!\n");
  2057.             cleanup();
  2058.             exit( 255 );
  2059.         }
  2060.  
  2061.         fprintf(stderr, "\nProcessing, please wait!\n");
  2062.  
  2063. /*
  2064. **  Read records, and process them.
  2065. */
  2066.  
  2067.         while( read_record() == SUCCESS )
  2068.             process_record();
  2069.  
  2070.     } /* end else if a test tape */
  2071.  
  2072. /*
  2073. **  Fix up the file size and the chunk size in the wave file.
  2074. **  Compute the lengths.  Write an alignment byte if needed.
  2075. **  Position the file at the chunk size and update it and do the
  2076. **  same for the file size.
  2077. */
  2078.     len_chunk = pos - pos_chunk_size - 4;
  2079.     len_file  = pos - pos_file_size - 4;
  2080.     if( len_chunk & 0x01L )
  2081.         write_wav( (char *)"\0", (uint32)1L );     /* Write alignment byte */
  2082.     fseek( wav_file, pos_chunk_size, SEEK_SET );   /* Go back to chunk size */
  2083.     write_wav_number( len_chunk, (uint32)4L );
  2084.     fseek( wav_file, pos_file_size, SEEK_SET );    /* Go back to file size */
  2085.     write_wav_number( len_file, (uint32)4L );
  2086.  
  2087.     cleanup();
  2088.     return 0;
  2089. }
  2090.  
  2091. /*****************************************************************************
  2092. **  MODIFICATION HISTORY
  2093. **
  2094. **  DATE        BY   Description
  2095. **  ----------  ---  ---------------------------------------------------------
  2096. **  1998/12/30  ERS  Project start
  2097. **  1999/04/26  ERS  Release 01.00
  2098. **
  2099. *****************************************************************************/
  2100.